package com.walter.epay.requestapi;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.walter.epay.constant.EpayApiConstant;
import com.walter.epay.exception.EpayCreateOrderException;
import com.walter.epay.exception.EpayGetOrderException;
import com.walter.epay.param.EpaySignParam;
import com.walter.epay.param.request.EapyClientStateParam;
import com.walter.epay.param.request.EpayCreateOrderParam;
import com.walter.epay.param.request.EpayGetOrderParam;
import com.walter.epay.param.request.EpayGetOrdersParam;
import com.walter.epay.param.response.EpayCreateOrderResponse;
import com.walter.epay.param.response.EpayGetOrdersResponse;
import com.walter.epay.param.response.EpayResponse;
import com.walter.epay.paramenum.createorder.EpayCreateOrderIsHtmlEnum;
import com.walter.epay.paramenum.createorder.EpayCreateOrderTypeEnum;
import com.walter.epay.util.EpaySignUtil;
import com.walter.epay.util.JsonUtil;

import java.security.NoSuchAlgorithmException;

/**
 * 发起接口请求
 *
 * @author wuchenxi
 * @date 2022-12-31 14:24:37
 */
public class EpayRequestApi {
    /**
     * 检查客户端在线状态
     *
     * @param param
     * @return
     */
    public static EpayResponse<Boolean> checkClientState(EapyClientStateParam param) {
        if (StrUtil.isEmpty(param.getMchId())) {
            throw new EpayGetOrderException("mchId 不能为空");
        }
        String url = EpayApiConstant.CHECK_CLIENT_STATE;
        System.out.println("请求地址：" + url + "，参数：" + JSONUtil.toJsonStr(param));
        String s = HttpUtil.get(url, BeanUtil.beanToMap(param));
        System.out.println("请求地址：" + url + "，参数：" + JSONUtil.toJsonStr(param) + "，响应：" + s);
        return JSONUtil.toBean(s, EpayResponse.class);
    }

    /**
     * 创建订单，返回订单json信息
     *
     * @param createOrderParam  创建订单参数
     * @param secret    商户秘钥
     * @return 订单json数据
     * @throws NoSuchAlgorithmException 加密异常
     * @throws EpayCreateOrderException 创建订单异常
     */
    public static EpayResponse<EpayCreateOrderResponse> createOrderWithJson(EpayCreateOrderParam createOrderParam, String secret) throws NoSuchAlgorithmException, EpayCreateOrderException {
        String response = createOrder(createOrderParam, secret);
        if (!JSONUtil.isTypeJSON(response)) {
            return EpayResponse.error(-1, response);
        }

        return JSONUtil.toBean(response, EpayResponse.class);
    }

    /**
     * 创建订单，返回订单扫码地址
     *
     * @param createOrderParam 创建订单参数
     * @param secret 商户秘钥
     * @return 响应数据是跳转到易支付支付页面的url
     * @throws NoSuchAlgorithmException 加密异常
     * @throws EpayCreateOrderException 创建订单异常
     */
    public static EpayResponse<String> createOrderWithHtml(EpayCreateOrderParam createOrderParam, String secret) throws NoSuchAlgorithmException, EpayCreateOrderException {
        String response = createOrder(createOrderParam, secret);
        if (JSONUtil.isTypeJSON(response) || !StrUtil.contains(response, "http")) {
            return EpayResponse.error(-1, response);
        }
        return EpayResponse.success(response);
    }

    /**
     * 查询订单信息
     *
     * @param param 查询订单参数
     * @return 订单信息
     * @throws EpayCreateOrderException 获取订单异常
     */
    public static EpayResponse<EpayCreateOrderResponse> getOrder(EpayGetOrderParam param) throws EpayGetOrderException {
        String url = EpayApiConstant.GET_ORDER;

        String s = getOrderRes(param, url);
        return JsonUtil.toEpayResponse(s, EpayCreateOrderResponse.class);
    }

    /**
     * 批量查询订单信息
     *
     * @param param
     * @return 订单信息
     * @throws EpayCreateOrderException
     */
    public static EpayResponse<EpayGetOrdersResponse> getOrders(EpayGetOrdersParam param) throws EpayGetOrderException {
        String url = EpayApiConstant.GET_ORDERS;

        if (param == null) {
            throw new EpayGetOrderException("批量查询订单信息参数不能为空");
        }
        if (CollUtil.isEmpty(param.getOrderIds())) {
            throw new EpayCreateOrderException("批量查询订单信息，订单编号不能为空");
        }
        if (StrUtil.isEmpty(param.getMchId())) {
            throw new EpayGetOrderException("批量查询订单信息，商户编号不能为空");
        }
        if (param.getPageNo() == null) {
            System.err.println("批量查询订单信息，pageNo参数为null了");
            param.setPageNo(1);
        }
        if (param.getPageSize() == null) {
            System.err.println("批量查询订单信息，pageSize参数为null了");
            param.setPageNo(20);
        }
        if (param.getPageSize() > 20) {
            System.err.println("批量查询订单信息，pageSize参数大于20了，pageSize=" + param.getPageSize());
            param.setPageNo(20);
        }
        if (param.getPageSize() <= 0) {
            System.err.println("批量查询订单信息，pageSize参数小于或者等于0了，pageSize=" + param.getPageSize());
            param.setPageNo(20);
        }
        System.out.println("请求地址：" + url + "，参数：" + JSONUtil.toJsonStr(param));
        String s = HttpUtil.get(url, BeanUtil.beanToMap(param));
        System.out.println("请求地址：" + url + "，参数：" + JSONUtil.toJsonStr(param) + "，响应：" + s);
        return JSONUtil.toBean(s, EpayResponse.class);
    }

    /**
     * 查询订单状态
     *
     * @param param 查询订单状态参数
     * @return 订单状态
     * @throws EpayCreateOrderException 查询订单状态异常
     */
    public static EpayResponse<EpayCreateOrderResponse> checkOrder(EpayGetOrderParam param) throws EpayGetOrderException {
        String url = EpayApiConstant.CHECK_ORDER;
        String s = getOrderRes(param, url);
        return JSONUtil.toBean(s, EpayResponse.class);
    }

    private static String getOrderRes(EpayGetOrderParam param, String url) {
        if (StrUtil.isEmpty(param.getOrderId())) {
            throw new EpayGetOrderException("orderId 不能为空");
        }
        if (StrUtil.isEmpty(param.getMchId())) {
            throw new EpayGetOrderException("mchId 不能为空");
        }

        System.out.println("请求地址：" + url + "，参数：" + JSONUtil.toJsonStr(param));
        String s = HttpUtil.get(url, BeanUtil.beanToMap(param));
        System.out.println("请求地址：" + url + "，参数：" + JSONUtil.toJsonStr(param) + "，响应：" + s);
        return s;
    }

    private static String createOrder(EpayCreateOrderParam createOrderParam, String secret) throws NoSuchAlgorithmException {
        checkCreateOrderParam(createOrderParam);

        EpaySignParam signParam = EpaySignParam.getCreateOrderSignStr(createOrderParam, secret);
        String sign = EpaySignUtil.getSign(signParam);

        createOrderParam.setSign(sign);

        System.out.println("请求地址:：" + EpayApiConstant.CREATE_ORDER + "，参数：" + BeanUtil.beanToMap(createOrderParam));
        String s = HttpUtil.get(EpayApiConstant.CREATE_ORDER, BeanUtil.beanToMap(createOrderParam));
        System.out.println("请求地址:：" + EpayApiConstant.CREATE_ORDER + "，参数：" + BeanUtil.beanToMap(createOrderParam) + "，响应：" + s);
        return s;
    }

    private static void checkCreateOrderParam(EpayCreateOrderParam param) {
        if (param == null) {
            throw new EpayCreateOrderException("createOrderParam 不能为空");
        }
        if (StrUtil.isBlank(param.getMchId())) {
            throw new EpayCreateOrderException("createOrderParam mchId不能为空");
        }
        if (param.getPayId() == null) {
            throw new EpayCreateOrderException("createOrderParam mchId不能为空");
        }
        if (param.getType() == null) {
            throw new EpayCreateOrderException("createOrderParam type不能为空");
        }
        if (EpayCreateOrderTypeEnum.getByCode(param.getType()) == null) {
            throw new EpayCreateOrderException("createOrderParam type参数不正确");
        }
        if (param.getPrice() == null) {
            throw new EpayCreateOrderException("createOrderParam price不能为空");
        }
        if (param.getPrice() <= 0) {
            throw new EpayCreateOrderException("createOrderParam price 支付金额必须大于0");
        }
        if (StrUtil.isBlank(param.getGoodsName())) {
            throw new EpayCreateOrderException("createOrderParam goodsName不能为空");
        }
        if (param.getGoodsName().length() > 50) {
            throw new EpayCreateOrderException("createOrderParam goodsName 长度不能大于50");
        }
        if (EpayCreateOrderIsHtmlEnum.getByCode(param.getIsHtml()) == null) {
            param.setIsHtml(EpayCreateOrderIsHtmlEnum.IS_JSON.getCode());
        }
        if (EpayCreateOrderTypeEnum.getByCode(param.getType()) == null) {
            throw new EpayCreateOrderException("createOrderParam type参数非法");
        }
        if (StrUtil.length(param.getNotifyUrl()) > 200) {
            throw new EpayCreateOrderException("createOrderParam notifiUrl 参数长度异常，最多200字符");
        }
        if (StrUtil.length(param.getReturnUrl()) > 200) {
            throw new EpayCreateOrderException("createOrderParam returnUrl 参数长度异常，最多200字符");
        }
    }
}
